﻿using System;
using System.Collections.Generic;
using System.Text;

namespace Axe.Geometry
{
    public static class Ecclipse
    {
        private static readonly double Xlog = Math.Log(2) / Math.Log(Math3D.PI / 2);
        private static readonly double XlogInv = Math.Log(Math3D.PI / 2) / Math.Log(2);

        #region static public float GetPerimenterF(float a, float b)
        /// <summary>
        /// Вычисление периметра эллипса
        /// </summary>
        /// <param name="a">Большая полуось</param>
        /// <param name="b">Меньшая полуось</param>
        /// <returns>Периметр</returns>
        public static float GetPerimenterF(float a, float b)
        {
            return 4.0f * (float)Math.Pow((Math.Pow(a, Xlog) + Math.Pow(b, Xlog)), XlogInv);
        } 
        #endregion

        #region static public double GetPerimenter(double a, double b)
        /// <summary>
        /// Вычисление периметра эллипса
        /// </summary>
        /// <param name="a">Большая полуось</param>
        /// <param name="b">Меньшая полуось</param>
        /// <returns>Периметр</returns>
        public static double GetPerimenter(double a, double b)
        {
            return 4.0 * Math.Pow((Math.Pow(a, Xlog) + Math.Pow(b, Xlog)), XlogInv);
        } 
        #endregion

        #region public static double GetEccentricity(double a, double b)
        public static double GetEccentricity(double a, double b)
        {
            return Math.Sqrt(a * a - b * b) / a;
        } 
        #endregion

        public static Vector2 GetPoint(double a, double b, double t)
        {
            double x = a * Math.Cos(t);
            double y = b * Math.Sin(t);

            return new Vector2(x,y);
        }
        
        public static void GetPoint(double a, double b, double t, Vector2 outPoint)
        {
            outPoint.X = a * Math.Cos(t);
            outPoint.Y = b * Math.Sin(t);
        }

        public static double GetFocus(double a, double b)
        {
            return Math.Sqrt(a * a - b * b);
        }

        public static double GetFocalDistance(double a, double b)
        {
            return 2.0 * Math.Sqrt(a * a - b * b);
        }

        public static float GetFocusF(double a, double b)
        {
            return (float)Math.Sqrt(a * a - b * b);
        }

        /// <summary>
        /// Вычисление длины меньшей полуоси эллипса (B)
        /// </summary>
        /// <param name="a">Большая полуось</param>
        /// <param name="e">Эксцентриситет</param>
        /// <returns>B</returns>
        public static double GetLessHalfAxis(double a, double e)
        {
            if (e < 0 || e >= 1)
                throw new ArgumentException("Invalid eccentricity");

            return a * Math.Sqrt(1 - e * e);
        }
    }
}
